package com.gxt.riaapp.client.mvc;

import java.util.Comparator;
import java.util.List;

import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.Style.SelectionMode;
import com.extjs.gxt.ui.client.data.BaseTreeLoader;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.TreeLoader;
import com.extjs.gxt.ui.client.data.TreeModel;
import com.extjs.gxt.ui.client.data.TreeModelReader;
import com.extjs.gxt.ui.client.event.EventType;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.event.SelectionService;
import com.extjs.gxt.ui.client.event.SourceSelectionChangedListener;
import com.extjs.gxt.ui.client.mvc.AppEvent;
import com.extjs.gxt.ui.client.mvc.Controller;
import com.extjs.gxt.ui.client.mvc.View;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.Store;
import com.extjs.gxt.ui.client.store.StoreSorter;
import com.extjs.gxt.ui.client.store.TreeStore;
import com.extjs.gxt.ui.client.util.IconHelper;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.ListView;
import com.extjs.gxt.ui.client.widget.TabItem;
import com.extjs.gxt.ui.client.widget.TabPanel;
import com.extjs.gxt.ui.client.widget.TabPanel.TabPosition;
import com.extjs.gxt.ui.client.widget.button.IconButton;
import com.extjs.gxt.ui.client.widget.form.StoreFilterField;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.extjs.gxt.ui.client.widget.treepanel.TreePanel;
import com.gxt.riaapp.client.AppEvents;
import com.gxt.riaapp.client.RiaApp;
import com.gxt.riaapp.client.mvc.model.Category;
import com.gxt.riaapp.client.mvc.model.Entry;

/**
 * AppView클래스의 WEST_PANEL을 구성한다.
 * 
 * @author KYS
 * 
 */
public class NavigationView extends View {
	private ContentPanel westPanel;
	private TabPanel tabPanel;
	private TabItem listItem, treeItem;
	
	private ToolBar toolBar;
	private StoreFilterField<ModelData> filter;
	private TreePanel<ModelData> tree;
	private TreeStore<ModelData> treeStore;
	
	private RiaAppModel model;
	
	@Override
	protected void initialize() {
		super.initialize();
		model = (RiaAppModel) Registry.get(RiaApp.MODEL);
		/**
		 * 트리내에서 다른 트리를 클릭했을 경우.
		 */
		SelectionService.get().addListener(
				new SelectionChangedListener<TreeModel>() {
					public void selectionChanged(SelectionChangedEvent<TreeModel> event) {
						List<TreeModel> sel = event.getSelection();
						if (sel.size() > 0) {
							TreeModel m = (TreeModel) event.getSelection().get(0);
							if (m != null && m instanceof Entry) {
								RiaApp.showPage((Entry) m);
							}
						}
					}
				}
		);
		// 필터 생성
		filter = new StoreFilterField<ModelData>() {
			@Override
			protected boolean doSelect(Store<ModelData> store,
					ModelData parent, ModelData child, String property,
					String filter) {
				
				String name = child.get("name");
				name = name.toLowerCase();
				if (name.indexOf(filter.toLowerCase()) != -1) return true;
				return false;
			}
		};
		// AppView의 좌측 패널로 정의된 ContentPanel을 얻어온다. 이렇게 얻어오기 위해선
		// AppView에 Registry.register(WEST_PANEL, westPanel); 와 같이 기술되어 있어야한다.
		westPanel = (ContentPanel) Registry.get(AppView.WEST_PANEL);
		westPanel.setHeading("Navigation");
		westPanel.setLayout(new FitLayout());
		westPanel.add(createTabPanel());
		
		toolBar = (ToolBar) westPanel.getTopComponent();
	    IconButton filterBtn = new IconButton("icon-filter");
	    
	    filterBtn.setWidth(20);
	    toolBar.add(filterBtn);
	    toolBar.add(filter);
	    
	    createListContent();  // ListItem구현
	    createTreeContent();	// TreeIem구현
	    
		westPanel.syncSize();
	}

	public NavigationView(Controller controller) {
		super(controller);
	}

	@Override
	protected void handleEvent(AppEvent event) {
	}
	
	private void createTreeContent() {
	    TreeLoader<ModelData> loader = new BaseTreeLoader<ModelData>(new TreeModelReader<List<ModelData>>()) {
	      @Override
	      public boolean hasChildren(ModelData parent) {
	        return parent instanceof Category;
	      }

	    };
	    treeStore = new TreeStore<ModelData>(loader);

	    tree = new TreePanel<ModelData>(treeStore);
	    tree.expandAll();
	    tree.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
	    tree.getStyle().setLeafIcon(IconHelper.createStyle("icon-list"));
	    tree.setDisplayProperty("name");

	    SelectionService.get().addListener(new SourceSelectionChangedListener(tree.getSelectionModel()));
	    SelectionService.get().register(tree.getSelectionModel());

	    filter.bind(treeStore);
	    loader.load(model); // RiaAppModel set
	    
	    treeItem.setBorders(false);
	    treeItem.setLayout(new FitLayout());
	    treeItem.add(tree);
	  }
	
	@SuppressWarnings("unchecked")
	private void createListContent() {
		listItem.setLayout(new FitLayout());
	    listItem.setBorders(false);

	    ListView<Entry> list = new ListView<Entry>();
	    list.setDisplayProperty("name");
	    list.setBorders(false); 
	    // ListItem에서 클릭시.
	    list.getSelectionModel().addSelectionChangedListener(new SelectionChangedListener<Entry>() {
	      @Override
	      public void selectionChanged(SelectionChangedEvent<Entry> se) {
	    	  Entry e = se.getSelection().get(0);
	        if (e != null && e instanceof Entry) {
	        	RiaApp.showPage((Entry) e);
	        }
	      }
	    });

	    ListStore<Entry> store = new ListStore<Entry>();
	    store.setStoreSorter(new StoreSorter(new Comparator<Entry>() {
	      public int compare(Entry e1, Entry e2) {
	        return e1.getName().compareTo(e2.getName());
	      }
	    }));
	    store.add(model.getEntries());
	    
	    list.setStore(store);

	    filter.bind((Store) store);
	    listItem.add(list);
	}

	private TabPanel createTabPanel() {
		tabPanel = new TabPanel();
		tabPanel.setMinTabWidth(70);
		tabPanel.setBorderStyle(false);
		tabPanel.setBodyBorder(false);
		tabPanel.setTabPosition(TabPosition.BOTTOM);

		treeItem = new TabItem();
		treeItem.setText("Tree");
		tabPanel.add(treeItem);

		listItem = new TabItem();
		listItem.setText("List");
		tabPanel.add(listItem);

		return tabPanel;
	}
}
